package com.siruier.boss.ui.interceptor

import cn.hutool.crypto.SecureUtil
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.didi.drouter.api.DRouter
import com.siruier.boss.api.core.ResultBean
import com.siruier.boss.common.ACTION_REQUEST
import com.siruier.boss.router.service.IUserService
import com.siruier.boss.ui.AppCore
import com.siruier.boss.ui.helper.localSendBroadcastSync
import com.siruier.boss.ui.utils.AesEncodeUtil
import com.siruier.boss.ui.utils.Logger
import com.siruier.boss.ui.utils.RequestAesUtil
import okhttp3.FormBody
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import okio.Buffer
import java.nio.charset.StandardCharsets


class ConvertInterceptor : Interceptor {
    companion object {
        private val DEFAULT_REQUEST_BODY = """{"timestamp":%d}""".trimIndent()
        val DEFAULT_RESULT = """{"msg":"未知错误","code":${ResultBean.SERVICE_ERROR}}""".trimIndent()
        private val CONTENT_TYPE = "application/json;charset=utf-8".toMediaType()
        private const val MEDIA_TYPE_SUB = "json"

    }

    private val mUserService: IUserService by lazy {
        DRouter.build(IUserService::class.java).getService()
    }

    override fun intercept(chain: Interceptor.Chain): Response {
        // 所有请求全部转换为 post json 请求
        var request = chain.request()
        val requestBody: RequestBody? = request.body
        var bodyJson: JSONObject? = null
        if ("POST" == request.method) {
            val formBody = requestBody as? FormBody
            if (formBody != null) {
                val param = JSONObject()
                for (i in 0 until formBody.size) {
                    param[formBody.name(i)] = formBody.value(i)
                }
                bodyJson = param
            } else if (MEDIA_TYPE_SUB == requestBody?.contentType()?.subtype) {
                bodyJson = JSON.parseObject(readBody(requestBody))
            }
        } else if ("GET" == request.method) {
            val param = JSONObject()
            val httpUrl = request.url
            for (i in httpUrl.queryParameterNames.indices) {
                param[httpUrl.queryParameterName(i)] = httpUrl.queryParameterValue(i)
            }
            bodyJson = param.ifEmpty {
                JSON.parseObject(readBody(null))
            }
        }
        if (bodyJson != null) {
            val signJson = JSONObject()
            Logger.e("加密前==>${bodyJson.toJSONString()}")
            signJson["encryptData"] = AesEncodeUtil.encrypt(bodyJson.toJSONString())
            request = request.newBuilder()
                .apply {
                    mUserService.getToken().takeIf { it.isNotEmpty() }?.let {
                        header("accessToken", it)
                    }
                }
                .post(signJson.toJSONString().toRequestBody(CONTENT_TYPE))
                .build()
        }
        val response = chain.proceed(request)
        if (response.isSuccessful) {
            if (MEDIA_TYPE_SUB == response.body?.contentType()?.subtype) {
                val body = try {
                    JSON.toJSONString(JSON.parseObject(response.body?.string()))
                } catch (e: Exception) {
                    DEFAULT_RESULT
                }
                return response.newBuilder().body(body.toResponseBody(CONTENT_TYPE)).build()
            }
            localSendBroadcastSync(AppCore.app, ACTION_REQUEST)
        }
        return response
    }

    private fun readBody(requestBody: RequestBody?): String {
        if (requestBody != null) {
            val buffer = Buffer()
            requestBody.writeTo(buffer)
            return buffer.readString(StandardCharsets.UTF_8)
        }
        return String.format(DEFAULT_REQUEST_BODY, System.currentTimeMillis())
    }
}